/*
 * @Author: xiaosihan 
 * @Date: 2023-12-19 23:04:12 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-01-07 18:37:31
 */

import { Euler, Group, InstancedBufferAttribute, InstancedMesh, Matrix4, Quaternion, Vector3 } from "three";
import MeshBase from "../MeshBase/MeshBase";

import SpriteVideo from "./SpriteVideo";
import { autorun, toJS } from "mobx";
import editor3DStore from "@views/editor3D/editor3DStore";
import InstancedGroupMesh from "../InstancedGroupMesh";
import ModelEventBox from "../ModelGroup/ModelEventBox";
import { degToRad } from "three/src/math/MathUtils";
import Hls from "hls.js";

// 监控设备组
export default class MonitorGroup extends Group {
    constructor(video: HTMLVideoElement) {
        super();
        this.video = video;
        this.loadModel();
    }

    static _position: Vector3 = new Vector3();
    static _scale: Vector3 = new Vector3(1, 1, 1);
    static _rotation: Euler = new Euler();
    static _Quaternion: Quaternion = new Quaternion();
    static _Matrix4: Matrix4 = new Matrix4();

    // 监控模型的实例对象
    monitorInstanceMesh!: InstancedGroupMesh;

    video!: HTMLVideoElement;

    hls = (() => {
        const hls = new Hls();
        hls.on(Hls.Events.MANIFEST_PARSED, () => {
            // this.video.play();
            // console.log("加载成功");
        });
        hls.on(Hls.Events.LEVEL_LOADED, () => {
            const { width, height } = hls.levels[0];
        });
        // hls.on(Hls.Events.ERROR, (event, data) => {
        //     //   console.log(event, data);
        //     // 监听出错事件
        //     console.log("加载失败");
        // });
        // hls.loadSource('https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8');
        // hls.attachMedia(this.video);

        return hls;
    })();

    url = "";

    // 设置视频流连接
    setUrl(url: string) {
        if (this.url !== url) {
            this.url = url;
            this.hls.loadSource(url);
            this.hls.attachMedia(this.video);
        }
    }

    // 视频弹窗
    // spriteVideo = (() => {
    //     const spriteVideo = new SpriteVideo();
    //     spriteVideo.position.set(0, 10, 0);
    //     this.add(spriteVideo);
    //     return spriteVideo;
    // })();

    //添加时的预览模型
    addPervire = (() => {
        const addPervire = new MeshBase("./data/monitor.glb");
        //根据状态控制鼠标事件
        autorun(() => {
            const { state } = editor3DStore;
            addPervire.visible = (state === "addMonitor");
        });
        this.add(addPervire);
        return addPervire;
    })();

    //高亮的监控模型
    heightLight = (() => {
        const heightLight = new MeshBase("./data/monitor.glb");

        heightLight.userData = {
            stroke_enable: true,//启用描边
            stroke_color: "#04fa12",//描边颜色
            stroke_width: 1,//描边厚度(像素)
        };

        //根据状态控制鼠标事件
        autorun(() => {
            const { activeMonitorId } = editor3DStore;
            const monitorData = editor3DStore.getMonitorDataById(activeMonitorId);
            if (monitorData) {
                const { positionX, positionY, positionZ, heading, pitch, roll, url } = monitorData;
                heightLight.visible = true;
                heightLight.position.set(positionX, positionY, positionZ);
                heightLight.rotation.set(heading, pitch, roll);
            } else {
                heightLight.visible = false;
            }
        });

        this.add(heightLight);
        return heightLight;
    })();

    // 加载监控模型
    loadModel() {
        const meshBase = new MeshBase("./data/monitor.glb");
        meshBase.addEventListener("loaded", () => {
            this.monitorInstanceMesh = new InstancedGroupMesh(meshBase, 0);
            this.add(this.monitorInstanceMesh);
        });
    }

    //模型点击盒子
    modelEventBox = (() => {
        const modelEventBox = new ModelEventBox();
        //three事件
        modelEventBox.userData = {
            cursor: "pointer",
            enableEvent: true,
        };
        //根据状态控制鼠标事件
        autorun(() => {
            const { state } = editor3DStore;
            // 添加模型时,事件盒子关闭鼠标事件
            Object.assign(modelEventBox.userData, { enableEvent: state === "" });
        });
        modelEventBox.addEventListener("click", (e:any) => {
            const monitorDatas = editor3DStore.getMonitorDatas();
            const monitorData = monitorDatas[e.instanceId];
            editor3DStore.setActiveMonitorId(monitorData.id);
        });
        this.add(modelEventBox);
        return modelEventBox;
    })();



    dispose = autorun(async () => {
        const { activeMonitorId } = editor3DStore;
        const monitorDatas = toJS(editor3DStore.monitorDatas);
        //等待模型加载完成
        while (!this.monitorInstanceMesh) {
            await new Promise(resolve => setTimeout(resolve, 200));
        }
        // 如果实例数量有改变就重新创建实例矩阵
        if (monitorDatas.length !== this.monitorInstanceMesh.count) {
            this.monitorInstanceMesh.count = monitorDatas.length;
            this.monitorInstanceMesh.children.map((instanceMesh: InstancedMesh) => {
                instanceMesh.count = monitorDatas.length;
                instanceMesh.instanceMatrix = new InstancedBufferAttribute(new Float32Array(monitorDatas.length * 16), 16);
            });
        }

        for (let i = 0; i < monitorDatas.length; i++) {

            // 设置矩阵
            MonitorGroup._position.set(monitorDatas[i].positionX, monitorDatas[i].positionY, monitorDatas[i].positionZ);
            MonitorGroup._rotation.set(
                degToRad(monitorDatas[i].heading),
                degToRad(monitorDatas[i].pitch),
                degToRad(monitorDatas[i].roll)
            );
            MonitorGroup._Quaternion.setFromEuler(MonitorGroup._rotation);

            // 不渲染当前选中的模型 有当前高亮对象来渲染
            if (activeMonitorId === monitorDatas[i].id) {
                MonitorGroup._scale.set(0, 0, 0);
            } else {
                MonitorGroup._scale.set(1, 1, 1);
            }

            MonitorGroup._Matrix4.compose(MonitorGroup._position, MonitorGroup._Quaternion, MonitorGroup._scale);
            this.monitorInstanceMesh.setMatrixAt(i, MonitorGroup._Matrix4);
        }

        // 创建点击模型盒的实例矩阵
        if (monitorDatas.length !== this.modelEventBox.count) {
            this.modelEventBox.count = monitorDatas.length;
            this.modelEventBox.instanceMatrix = new InstancedBufferAttribute(new Float32Array(monitorDatas.length * 16), 16);
        }

        //设置点击模型盒的矩阵
        for (let i = 0; i < monitorDatas.length; i++) {
            // 设置矩阵
            MonitorGroup._position.set(monitorDatas[i].positionX, monitorDatas[i].positionY, monitorDatas[i].positionZ);
            MonitorGroup._scale.copy(this.monitorInstanceMesh.size);
            MonitorGroup._rotation.set(
                degToRad(monitorDatas[i].heading),
                degToRad(monitorDatas[i].pitch),
                degToRad(monitorDatas[i].roll)
            );
            MonitorGroup._Quaternion.setFromEuler(MonitorGroup._rotation);
            MonitorGroup._Matrix4.compose(MonitorGroup._position, MonitorGroup._Quaternion, MonitorGroup._scale);
            this.modelEventBox.setMatrixAt(i, MonitorGroup._Matrix4);
        }
        this.modelEventBox.instanceMatrix.needsUpdate = true;
        this.modelEventBox.computeBoundingSphere();

    });

}